﻿using SorketServer.Common;
using SorketServer.HYModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static SorketServer.LedDll;

namespace SorketServer
{
    public partial class CarMain : Form
    {
        bool needClose = false;
        public CarMain()
        {
            InitializeComponent();
            this.Load += CarMain_Load;
            this.FormClosing += CarMain_FormClosing;
        }

        private void CarMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            needClose = true;
        }
        int hProgram;//节目句柄
        int nResult;
        WATERBORDERINFO info;
        LedDll.FONTPROP fontProp10;
        LedDll.FONTPROP fontProp12;
        LedDll.FONTPROP fontProp14;

        LedDll.PLAYPROP playProp;
        List<CarRecord> list = new List<CarRecord>();
        bool needRefresh = false;
        SystemConfig config = null;
        private void CarMain_Load(object sender, EventArgs e)
        {

            // List<DepartCountDto> list = CarHelper.GetDepartCount();

            CarIn carIn1 = new CarIn("苏L123456",1);
            carIn1.Show();

            Task.Factory.StartNew(() =>
            {
                try
                {
                    IPAddress ip = IPAddress.Parse("127.0.0.1");
                    IPEndPoint ipe = new IPEndPoint(ip, 8089);//把ip和端口转化为IPEndPoint实例

                    Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个Socket
                    server.Bind(ipe);//绑定2000端口
                    server.Listen(0);//开始监听
                    Socket temp = null;
                    CarIn carIn = null;
                    while (!needClose)
                    {
                        temp = server.Accept();//为新建连接创建新的Socket。
                        string recvStr = "";
                        byte[] recvBytes = new byte[10240];
                        int bytes;
                        bytes = temp.Receive(recvBytes, recvBytes.Length, 0);//从客户端接受信息
                        recvStr += Encoding.UTF8.GetString(recvBytes, 0, bytes);

                        string sendStr = "";
                        byte[] bs = Encoding.UTF8.GetBytes(sendStr);
                        temp.Send(bs, bs.Length, 0);//返回客户端成功信息
                        temp.Close();
                        if (carIn == null)
                        {
                            string[] array = recvStr.Split(',');
                            int num = Convert.ToInt32(array[0]);
                            carIn = new CarIn(array[1], num);
                            carIn.ShowDialog();
                            carIn = null;

                        }
                      
                        GC.Collect();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

            });

            InitData();
            config = CarHelper.GetConfig();
            Task.Run(() =>
            {
                try
                {
                    while (true)
                    {
                        var newList = CarHelper.GetInList();
                        if (newList.Count != list.Count || needRefresh || newList.Count == 0)
                        {
                            list = newList;
                            LedDll.COMMUNICATIONINFO CommunicationInfo = new LedDll.COMMUNICATIONINFO();//定义一通讯参数结构体变量用于对设定的LED通讯，具体对此结构体元素赋值说明见COMMUNICATIONINFO结构体定义部份注示
                            CommunicationInfo.SendType = 0;//设为固定IP通讯模式，即TCP通讯
                            CommunicationInfo.IpStr = ConfigurationManager.AppSettings["IP"].ToString(); ;//给IpStr赋值LED控制卡的IP
                            CommunicationInfo.LedNumber = 1;//LED屏号为1，注意socket通讯和232通讯不识别屏号，默认赋1就行了，485必需根据屏的实际屏号进行赋值

                            hProgram = LedDll.LV_CreateProgram(192, 144, 2);
                            int num = 1;
                            config = CarHelper.GetConfig();
                            if (list.Count < 8)
                            {
                                nResult = LedDll.LV_AddProgram(hProgram, num, 0, 1);//添加一个节目，参数说明见函数声明注示
                                CreateCarPlate(1);
                            }
                            else
                            {
                                nResult = LedDll.LV_AddProgram(hProgram, num, 10, 1);//添加一个节目，参数说明见函数声明注示
                                num++;
                                nResult = LedDll.LV_AddProgram(hProgram, num, 10, 1);
                                CreateCarPlate(1);
                                CreateCarPlate(2);
                            }

                            nResult = LedDll.LV_Send(ref CommunicationInfo, hProgram);//发送，见函数声明注示
                            LedDll.LV_DeleteProgram(hProgram);
                            if (nResult != 0)//如果失败则可以调用LV_GetError获取中文错误信息
                            {
                                string ErrStr;
                                ErrStr = LedDll.LS_GetError(nResult);

                            }
                            else
                            {

                            }

                        }

                        Thread.Sleep(5000);
                    }
                }
                catch (Exception ex)
                {

                    MessageBox.Show(ex.Message + "2");
                }

            });
            try
            {
              
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message + "3");
            }

        }

        void CreateAnouce(int no,string title,string content)
        {
            LedDll.AREARECT areaReact = GetReact(0, 4, 192, 20);
            LedDll.LV_AddImageTextArea(hProgram, no, 1, ref areaReact, 0);
            nResult = LedDll.LV_AddMultiLineTextToImageTextArea(hProgram, no, 1, LedDll.ADDTYPE_STRING, title, ref fontProp12, ref playProp, 2, 0);//通过字符串添加一个多行文本到图文区，参数说明见声明注示

            areaReact = GetReact(0, 24, 192, 110);
            LedDll.LV_AddImageTextArea(hProgram, no, 2, ref areaReact, 0);
            nResult = LedDll.LV_AddMultiLineTextToImageTextArea(hProgram, no, 1, LedDll.ADDTYPE_STRING, content, ref fontProp12, ref playProp,0, 0);//通过字符串添加一个多行文本到图文区，参数说明见声明注示

        }
        void InitData()
        {
            info = new WATERBORDERINFO()
            {
                BorderColor = LedDll.COLOR_RED,
                BorderSpeed = 4,
                BorderType = 0,
                BorderValue = 0,
                BorderStyle = 0,
                Flag = 0

            };


            fontProp10 = new LedDll.FONTPROP();//文字属性
            fontProp10.FontName = "宋体";
            fontProp10.FontSize = 10;
            fontProp10.FontColor = LedDll.COLOR_RED;
            fontProp10.FontBold = 0;

            fontProp12 = new LedDll.FONTPROP();//文字属性
            fontProp12.FontName = "宋体";
            fontProp12.FontSize = 12;
            fontProp12.FontColor = LedDll.COLOR_RED;
            fontProp12.FontBold = 0;

            fontProp14 = new LedDll.FONTPROP();//文字属性
            fontProp14.FontName = "宋体";
            fontProp14.FontSize = 14;
            fontProp14.FontColor = LedDll.COLOR_RED;
            fontProp14.FontBold = 0;

            playProp = new LedDll.PLAYPROP();
            playProp.InStyle = 23;
            playProp.DelayTime = 65535;
            playProp.Speed =1;

        }

        void CreateCarPlate(int no)
        {
            LedDll.AREARECT areaReact = GetReact(0, 4, 192, 20);
            LedDll.LV_AddImageTextArea(hProgram, no, 1, ref areaReact, 0);
            nResult = LedDll.LV_AddMultiLineTextToImageTextArea(hProgram, no, 1, LedDll.ADDTYPE_STRING, config.Company, ref fontProp12, ref playProp, 2, 0);//通过字符串添加一个多行文本到图文区，参数说明见声明注示
            var temp = list;
            if (no == 1)
            {
                temp = list.Take(8).ToList();
            }
            else
            {
                temp = list.Skip(8).Take(8).ToList();
            }
            string str1 = "车牌\r\n";
            string str2 = "人数\r\n";
            for (var i = 0; i < temp.Count; i++)
            {
                str1 = str1 + temp[i].CarPlant + "\r\n";
                str2 = str2 + temp[i].PersonNum + "\r\n";
            }
            areaReact = GetReact(0, 24, 96, 104);
            LedDll.LV_AddImageTextArea(hProgram, no, 2, ref areaReact, 0);
            nResult = LedDll.LV_AddMultiLineTextToImageTextArea(hProgram, no, 2, LedDll.ADDTYPE_STRING, str1, ref fontProp10, ref playProp, 2, 0);//通过字符串添加一个多行文本到图文区，参数说明见声明注示
            areaReact = GetReact(96, 24, 96, 104);
            LedDll.LV_AddImageTextArea(hProgram, no, 3, ref areaReact, 0);
            nResult = LedDll.LV_AddMultiLineTextToImageTextArea(hProgram, no, 3, LedDll.ADDTYPE_STRING, str2, ref fontProp10, ref playProp, 2, 0);//通过字符串添加一个多行文本到图文区，参数说明见声明注示

            areaReact = GetReact(0, 128, 192, 15);
            nResult = LedDll.LV_QuickAddSingleLineTextArea(hProgram, no, 4, ref areaReact, LedDll.ADDTYPE_STRING, "    " + config.Anounce, ref fontProp14, 1);//快速通过字符添加一个单行文本区域，函数见函数声明注示

        }

        string GetLength(string str, int total)
        {
            if (str.Length == 0) return "";
            ASCIIEncoding ascii = new ASCIIEncoding();
            int templen = 0;
            byte[] s = ascii.GetBytes(str);
            for (int i = 0; i < s.Length; i++)
            {
                if ((int)s[i] == 63)
                {
                    templen += 2;
                }
                else
                {
                    templen += 1;
                }
            }
            string temp = str.PadLeft((total - templen) / 2 + str.Length, ' ');
            return str.PadLeft((total - templen) / 2 + str.Length, ' ');

        }
        int GetLength(string str)
        {
            if (str.Length == 0) return 0;
            ASCIIEncoding ascii = new ASCIIEncoding();
            int templen = 0;
            byte[] s = ascii.GetBytes(str);
            for (int i = 0; i < s.Length; i++)
            {
                if ((int)s[i] == 63)
                {
                    templen += 2;
                }
                else
                {
                    templen += 1;
                }
            }
            return templen;
        }
        public  string GetSubString(string str, int length, bool flag)
        {
            string temp = str;
            int j = 0;
            int k = 0;
            for (int i = 0; i < temp.Length; i++)
            {
                if (Regex.IsMatch(temp.Substring(i, 1), @"[\u4e00-\u9fa5]+"))
                {
                    j += 2;
                }
                else
                {
                    j += 1;
                }
                if (j <= length)
                {
                    k += 1;
                }
                if (j >= length)
                {
                    temp = temp.Substring(0, k);
                    break;
                }
            }
            if (flag)
            {
                temp += "...";
            }
            return temp;
        }
        List<string> GetSp(string str)
        {
            List<string> array = new List<string>();
            int len = GetLength(str);
            int total = 24 * 9;
            int count = (int)Math.Ceiling(((decimal)len/ total));
            for (int i = 0; i < count; i++)
            {
                string newStr = GetSubString(str, total, false);
                array.Add(newStr);
                str = str.Remove(0,newStr.Length);
            }

            return array;

        }
        void CreateFirst()
        {
            LedDll.AREARECT areaReact = GetReact(0, 0, 192, 24);
            nResult = LedDll.LV_AddWaterBorder(hProgram, 1, 1, ref areaReact, ref info);
            areaReact = GetReact(1, 1, 190, 22);
            LedDll.LV_AddImageTextArea(hProgram, 1, 2, ref areaReact, 0);
            nResult = LedDll.LV_AddMultiLineTextToImageTextArea(hProgram, 1, 2, LedDll.ADDTYPE_STRING, "      安全承诺公告", ref fontProp12, ref playProp, 0, 0);//通过字符串添加一个多行文本到图文区，参数说明见声明注示

            areaReact = GetReact(0, 24, 26, 120);
            nResult = LedDll.LV_AddWaterBorder(hProgram, 1, 3, ref areaReact, ref info);
            areaReact = GetReact(1, 25, 24, 118);
            LedDll.LV_AddImageTextArea(hProgram, 1, 4, ref areaReact, 0);
            nResult = LedDll.LV_AddMultiLineTextToImageTextArea(hProgram, 1, 4, LedDll.ADDTYPE_STRING, "               企业状态", ref fontProp10, ref playProp, 0, 0);//通过字符串添加一个多行文本到图文区，参数说明见声明注示

            areaReact = GetReact(26, 24, 160, 20);
            nResult = LedDll.LV_AddWaterBorder(hProgram, 1, 5, ref areaReact, ref info);
            areaReact = GetReact(27, 25, 158, 18);
            LedDll.LV_AddImageTextArea(hProgram, 1, 6, ref areaReact, 0);
            nResult = LedDll.LV_AddMultiLineTextToImageTextArea(hProgram, 1, 6, LedDll.ADDTYPE_STRING, "生产装置  套 其中", ref fontProp10, ref playProp, 0, 0);//通过字符串添加一个多行文本到图文区，参数说明见声明注示

            areaReact = GetReact(26, 44, 160, 20);
            nResult = LedDll.LV_AddWaterBorder(hProgram, 1, 7, ref areaReact, ref info);
            areaReact = GetReact(27, 45, 158, 18);
            LedDll.LV_AddImageTextArea(hProgram, 1, 8, ref areaReact, 0);
            nResult = LedDll.LV_AddMultiLineTextToImageTextArea(hProgram, 1, 8, LedDll.ADDTYPE_STRING, "运行  套;停用  套;检修  套;", ref fontProp10, ref playProp, 0, 0);//通过字符串添加一个多行文本到图文区，参数说明见声明注示



            areaReact = GetReact(26, 64, 160, 40);
            nResult = LedDll.LV_AddWaterBorder(hProgram, 1, 9, ref areaReact, ref info);
            areaReact = GetReact(27, 65, 158, 38);
            LedDll.LV_AddImageTextArea(hProgram, 1, 10, ref areaReact, 0);
            nResult = LedDll.LV_AddMultiLineTextToImageTextArea(hProgram, 1, 10, LedDll.ADDTYPE_STRING, "特殊动火  处;一级动火 处;二级动火  处", ref fontProp10, ref playProp, 0, 0);//通过字符串添加一个多行文本到图文区，参数说明见声明注示

            areaReact = GetReact(26, 104, 160, 20);
            nResult = LedDll.LV_AddWaterBorder(hProgram, 1, 11, ref areaReact, ref info);
            areaReact = GetReact(27, 105, 158, 18);
            LedDll.LV_AddImageTextArea(hProgram, 1, 12, ref areaReact, 0);
            nResult = LedDll.LV_AddMultiLineTextToImageTextArea(hProgram, 1, 12, LedDll.ADDTYPE_STRING, "进入受限空间作业  处", ref fontProp10, ref playProp, 0, 0);//通过字符串添加一个多行文本到图文区，参数说明见声明注示

            areaReact = GetReact(26, 124, 160, 20);
            nResult = LedDll.LV_AddWaterBorder(hProgram, 1, 13, ref areaReact, ref info);
            areaReact = GetReact(27, 125, 158, 18);
            LedDll.LV_AddImageTextArea(hProgram, 1, 14, ref areaReact, 0);
            nResult = LedDll.LV_AddMultiLineTextToImageTextArea(hProgram, 1, 14, LedDll.ADDTYPE_STRING, "是否处于试生产", ref fontProp10, ref playProp, 0, 0);//通过字符串添加一个多行文本到图文区，参数说明见声明注示

        }


        LedDll.AREARECT GetReact(int left, int top, int width, int height)
        {
            LedDll.AREARECT AreaRect = new LedDll.AREARECT();//区域坐标属性结构体变量
            AreaRect.left = left;
            AreaRect.top = top;
            AreaRect.width = width;
            AreaRect.height = height;
            return AreaRect;

        }

        private void button1_Click(object sender, EventArgs e)
        {
            SystemConfig config = new SystemConfig();
            //config.Company = txtCompany.Text.Trim();
            //config.Titile = txtTitle.Text;
            //config.Content = txtContent.Text;
            CarHelper.SaveConfig(config);
            needRefresh = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //txtTitle.Text = "";
            //txtContent.Text = "";
            //txtCompany.Text = "";
        }
    }
}
